【小ネタ】CloudWatchアラーム群を定期的にON, OFFする仕組みをCloudFormationテンプレートで作成する
特定の時間だけCloudWatchアラームを OFFにして、通知を抑制しようとしています。 抑制の仕組みは、今では EventBridgeスケジューラー を使えば比較的簡単に実装できます。 以下ブログです。
▲ 上記ブログより画像を引用
本ブログはこの仕組みをCloudFormationテンプレート化してみます。 複数プロジェクトのCWアラーム群を効率よく制御したいのが テンプレート化のモチベーションです。
CloudFormationテンプレートを書いた
早速ですがテンプレートを書きました。
AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::LanguageExtensions Parameters: Project: Type: String ScheduleExpressionOFF: Type: String ScheduleExpressionON: Type: String AlarmNames: Type: CommaDelimitedList Resources: # EventBridge Scheduler (Disable CloudWatch Alarms) ScheduleCWAlarmOFF: Type: AWS::Scheduler::Schedule Properties: Name: !Sub "${Project}-cwalarm-off" Description: !Sub "Disable ${Project} CloudWatch Alarms" ScheduleExpression: !Ref ScheduleExpressionOFF ScheduleExpressionTimezone: "Japan" FlexibleTimeWindow: Mode: "OFF" State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:cloudwatch:disableAlarmActions Input: Fn::ToJsonString: AlarmNames: !Ref AlarmNames RoleArn: !GetAtt "SchedulerRole.Arn" # EventBridge Scheduler (Enable CloudWatch Alarms) ScheduleCWAlarmON: Type: AWS::Scheduler::Schedule Properties: Name: !Sub "${Project}-cwalarm-on" Description: !Sub "Enable ${Project} CloudWatch Alarms" ScheduleExpression: !Ref ScheduleExpressionON ScheduleExpressionTimezone: "Japan" FlexibleTimeWindow: Mode: "OFF" State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:cloudwatch:enableAlarmActions Input: Fn::ToJsonString: AlarmNames: !Ref AlarmNames RoleArn: !GetAtt "SchedulerRole.Arn" # Role for EventBridge Scheduler SchedulerRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${Project}-scheduler-role-for-cwalarm" AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - scheduler.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: CloudWatchAlarmONOFF PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - cloudwatch:DisableAlarmActions - cloudwatch:EnableAlarmActions Resource: - "*"
指定するパラメータ(Parameters)
以下 4つのパラメータを指定します。
- Project : プロジェクト名。スケジュール名のプレフィクスになります
- ScheduleExpressionOFF : アラームを無効化させたい時刻の cron です
- ScheduleExpressionON : アラームを有効化させたい時刻の cron です
- AlarmNames : 対象のアラーム群です (カンマ区切り)
作られるリソース(Resources)
以下 3リソースが作られます。
- ScheduleCWAlarmOFF : 指定した時刻(ScheduleExpressionON)に 指定したCWアラーム(AlarmNames) を無効化する EventBridgeスケジューラ
- ScheduleCWAlarmON : 指定した時刻(ScheduleExpressionON)に 指定したCWアラーム(AlarmNames) を有効化する EventBridgeスケジューラ
- SchedulerRole : 上記 2つの EventBridgeスケジューラで使われるIAMロール
展開してみる
事前に 2つのCWアラームを用意しました (ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm)。 これらを定期的にON,OFFする仕組みを展開します。
CLIで展開
CloudShellから AWS CLI でテンプレートを展開します。 template_body に 先程のCFnテンプレートyamlを指定します。
### スタック展開の各種パラメータ stack_name="example-cwalarms-on-off-schedule" template_body="./example/template.yaml" project="example" cron_off="cron(20 09 * * ? *)" cron_on="cron(25 09 * * ? *)" alarm_names="ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm" ### スタック展開 aws cloudformation create-stack \ --stack-name "${stack_name}" \ --template-body "file://${template_body}" \ --parameters \ "[ {\"ParameterKey\": \"Project\", \"ParameterValue\": \"${project}\"} , {\"ParameterKey\": \"ScheduleExpressionOFF\", \"ParameterValue\": \"${cron_off}\"} , {\"ParameterKey\": \"ScheduleExpressionON\", \"ParameterValue\": \"${cron_on}\"} , {\"ParameterKey\": \"AlarmNames\", \"ParameterValue\": \"${alarm_names}\"} ]" \ --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
このパラメータで作られるリソースは以下のとおりです。 (検証のために off にしている時間を 5分間にしています)
- example-cwalarm-off : 毎日 09:20 に CWアラーム(ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm)を 無効化するEventBridgeスケジューラ
- example-cwalarm-on : 毎日 09:25 に CWアラーム(ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm)を 有効化するEventBridgeスケジューラ
- example-scheduler-role-for-cwalarm : 上記 2つの EventBridgeスケジューラで使われるIAMロール
展開後の確認
以下のように、期間中にアクションが無効化されていることを確認できました。
おわりに
以上、CWアラームのON,OFFをスケジュールする仕組みをCFnテンプレート化してみました。
内容自体は すでにあるブログ の二番煎じですが、 「沢山のスケジュールを展開したい!」といったときに役に立てば幸いです。